/* eslint-disable import/no-extraneous-dependencies */
import * as d3 from 'd3';

export default class Chart {
  constructor() {
    this.widthData = 1200; // document.body.clientWidth
    this.heightData = 700; // document.body.clientHeight
    this.marginsData = {
      top: 30, left: 30, right: 30, bottom: 30,
    };
    this.dataArr = [];
    this.scaleXData = null;
    this.scaleYData = null;
    this.colors = d3.scaleOrdinal(d3.schemeCategory10);
    this.boxData = null;
    this.svgData = null;
    this.bodyData = null;
    this.paddingData = {
      top: 10, left: 10, right: 10, bottom: 10,
    };
  }

  width(w) {
    if (arguments.length === 0) return this.widthData;
    this.widthData = w;
    return this;
  }

  height(h) {
    if (arguments.length === 0) return this.heightData;
    this.heightData = h;
    return this;
  }

  margins(m) {
    if (arguments.length === 0) return this.marginsData;
    this.marginsData = m;
    return this;
  }

  data(d) {
    if (arguments.length === 0) return this.dataArr;
    this.dataArr = d;
    return this;
  }

  scaleX(x) {
    if (arguments.length === 0) return this.scaleXData;
    this.scaleXData = x;
    return this;
  }

  scaleY(y) {
    if (arguments.length === 0) return this.scaleYData;
    this.scaleYData = y;
    return this;
  }

  svg(s) {
    if (arguments.length === 0) return this.svgData;
    this.svgData = s;
    return this;
  }

  body(b) {
    if (arguments.length === 0) return this.bodyData;
    this.bodyData = b;
    return this;
  }

  box(b) {
    if (arguments.length === 0) return this.boxData;
    this.boxData = b;
    return this;
  }

  getBodyWidth() {
    const widthData = this.widthData - this.marginsData.left - this.marginsData.right;
    return widthData > 0 ? widthData : 0;
  }

  getBodyHeight() {
    const heightData = this.heightData - this.marginsData.top - this.marginsData.bottom;
    return heightData > 0 ? heightData : 0;
  }

  padding(p) {
    if (arguments.length === 0) return this.paddingData;
    this.paddingData = p;
    return this;
  }

  defineBodyClip() {
    this.svgData.append('defs')
      .append('clipPath')
      .attr('id', 'clip')
      .append('rect')
      .attr('width', this.getBodyWidth() + this.paddingData.left + this.paddingData.right)
      .attr('height', this.getBodyHeight() + this.paddingData.top + this.paddingData.bottom)
      .attr('x', -this.paddingData.left)
      .attr('y', -this.paddingData.top);
  }

  render() {
    return this;
  }

  bodyX() {
    return this.marginsData.left;
  }

  bodyY() {
    return this.marginsData.top;
  }

  renderBody() {
    if (!this.bodyData) {
      this.bodyData = this.svgData.append('g')
        .attr('class', 'body')
        .attr('transform', `translate(${this.bodyX()},${this.bodyY()})`)
        .attr('clip-path', 'url(#clip)');
    }

    this.render();
  }

  renderChart(name) {
    if (!this.boxData) {
      this.boxData = d3.select(name)
        .append('div')
        .attr('class', 'box');
    }

    if (!this.svgData) {
      this.svgData = this.boxData.append('svg')
        .attr('width', this.widthData)
        .attr('height', this.heightData);
    }

    this.defineBodyClip();

    this.renderBody();
  }
}
